#include "../../HeadFiles/ChainsH/CommodityChain.h"
#include "../../HeadFiles/ChainsH/RecordChain.h"
#include "../../HeadFiles/InputCheck.h"
#include "../../HeadFiles/StrSimilar.h"
void displayAllCommodities(struct CommodityNode * head)
{
    int idx = 0;
    while(head != NULL) {
        puts(SPLIT_STR);

        // 以下代码用来展示每个记录的细节信息， 做成代码块方便折叠
        {
            printf("Commodity #%d:\n", ++idx);
            printf("CommodityName = %s\n", head->commodityName);
            printf("CommodityPurchasePrice = %.2f\n", head->purchasePrice);
            printf("CommoditySoldPrice = %.2f\n", head->soldPrice);
            printf("CommodityUnitCount = %d\n", head->unitCount);
        }
    head = head->nextCommodity;
    }
    puts(SPLIT_STR);
    puts("Commodities Display Finished");
}

void buildCommodityChain(struct CommodityNode ** head, struct CommodityNode ** tail)
{
    FILE * commodityFILE = fopen("../Data/CommodityChainData/CommodityData.txt", "r");

    * head = * tail = NULL; // 先初始化防止不操作返回野值
    int opt;
    fscanf(commodityFILE, "%d", &opt); // opt==-1为停止添加节点，==1为添加新节点
    struct CommodityNode * pre = NULL, * now = NULL;
    while(opt == 1)
    {
        now = (struct CommodityNode *)malloc(sizeof(struct CommodityNode));
        now->nextCommodity = now->preCommodity = NULL; // 申请完空间直接把指针初始化

        // 以下代码用来录入每个记录的细节信息， 做成代码块方便折叠
        {
            fscanf(commodityFILE, "%s", &now->commodityName);
            fscanf(commodityFILE, "%lf", &now->purchasePrice);
            fscanf(commodityFILE, "%lf", &now->soldPrice);
            fscanf(commodityFILE, "%d", &now->unitCount);
            // fscanf("")
        }

        if(* head == NULL)
        {
            * head = now;
        }else{
            pre->nextCommodity = now;
            now->preCommodity = pre;
        }
        pre = now;
        fscanf(commodityFILE, "%d", &opt);
    }
    * tail = now;

    fclose(commodityFILE);
    commodityFILE = NULL;
}

void  delCommodity(struct CommodityNode ** head, struct CommodityNode ** tail, struct CommodityNode * p)
{
    // ** head, ** tail是头尾指针的地址，直接对其解引用，然后加以修改
    // 注意，p是指向节点的指针，和head，tail不一样
    if(* head == p || * tail == p)
    {
        // 如果要删除的节点比较特殊，是头或尾节点
        if(* head == p && * tail == p)
        {
            // 要删除的节点既是头又是尾， 此时链表只有这一个元素
            free(* head);
            * head = * tail = NULL; // free后内存被清理，但是指针仍指向该地址，必须置空防bug
            return ;
        }
        if(* head == p && * tail != p)
        {
            // 要删除的节点是头，但不是尾
            struct CommodityNode * temp = * head;
            * head = (* head)->nextCommodity;
            (* head)->preCommodity = NULL;
            free(temp);
            return ;
        }
        if(* head != p && * tail == p)
        {
            // 要删除的节点是尾，但不是头
            struct CommodityNode * temp = * tail;
            * tail = (* tail)->preCommodity;
            (* tail)->nextCommodity = NULL;
            free(temp);
            return ;
        }
    }
    // 如果删除的节点不是头或者尾的特殊情况
    // 注意，p是指向节点的指针，和head，tail不一样
    p->nextCommodity->preCommodity = p->preCommodity;
    p->preCommodity->nextCommodity = p->nextCommodity;
    free(p);
}

void displayThisCommodity(struct CommodityNode * commodityDisplayPtr)
{
    // commodityDisplayPtr是为了在主函数中区分不同的链表当前展示指针
    // 在函数里写成this方便阅读
    struct CommodityNode * this = commodityDisplayPtr;
    puts(SPLIT_STR);

    printf("CommodityName: %s\n", this->commodityName);
    // 此处暂时输出两位小数
    printf("CommodityPurchasePrice = %.2f\n", this->purchasePrice);
    printf("CommodityUnitPrice: %.2f\n", this->soldPrice);
    printf("CommodityUnitCount: %d\n", this->unitCount);

    puts(SPLIT_STR);
}
void rebuildCommodityFile(struct CommodityNode * head)
{
    FILE * commodityFile = fopen("../Data/CommodityChainData/CommodityData.txt", "w");

    while(head != NULL)
    {
        // 输出节点所有信息的代码块，在测试时，暂时只输出unit count
        {
            fprintf(commodityFile, "1\n");
            fprintf(commodityFile, "%s\n", head->commodityName);
            fprintf(commodityFile, "%.2f\n", head->purchasePrice);
            fprintf(commodityFile, "%.2f\n", head->soldPrice);
            fprintf(commodityFile, "%d\n", head->unitCount);
            fprintf(commodityFile, "\n");
            head = head->nextCommodity;
        }
    }
    fputs("-1", commodityFile);

    fclose(commodityFile);
    commodityFile = NULL;
}
void addCommodity(struct CommodityNode ** head, struct CommodityNode ** tail)
{
    struct CommodityNode * now = (struct CommodityNode *) malloc(sizeof(struct CommodityNode));
    now->preCommodity = now->nextCommodity = NULL;    // 申请新节点第一件事就是指针初始化！非常重要！

    if(* head == NULL && * tail == NULL)
    {
        // 增加链表第一个节点,该节点即是头又是尾
        puts("You are now creating the 1st commodity");
        * head = * tail = now;
        // 输入具体信息的代码块
        {
            puts("Input commodity name:");
            scanf("%s", now->commodityName);

            puts("Input commodity purchase price:");
            char tempPurchasePrice[STR_MAX_LEN];
            scanf("%s", tempPurchasePrice);
            while(!(isStandardFloat(tempPurchasePrice) || isFullDigit(tempPurchasePrice))
             && strlen(tempPurchasePrice) <= 8)
            {
                puts("Illegal input Detected!Try again:");
                scanf("%s", tempPurchasePrice);
            }//解决输入不知道加没加小数点的情况
            if(isStandardFloat(tempPurchasePrice)==true)
                now->purchasePrice = strToDouble(tempPurchasePrice);
            else if(isFullDigit(tempPurchasePrice)==true)
                now->purchasePrice = intStrToDouble(tempPurchasePrice);

            puts("Input commodity unit price:");
            char tempUnitPrice[STR_MAX_LEN];
            scanf("%s", tempUnitPrice);
            while(!(isStandardFloat(tempUnitPrice) || isFullDigit(tempUnitPrice))
                  && strlen(tempUnitPrice) <= 8)
            {
                puts("Illegal input Detected!Try again:");
                scanf("%s", tempUnitPrice);
            }//解决输入不知道加没加小数点的情况
            if(isStandardFloat(tempUnitPrice)==true)
                now->soldPrice = strToDouble(tempUnitPrice);
            else if(isFullDigit(tempUnitPrice)==true)
                now->soldPrice = intStrToDouble(tempUnitPrice);
        }
        return ;
    }else{
        // 不是第一个节点，则只需接在最后节点(tail)的后面
        (* tail)->nextCommodity = now;
        now->preCommodity = * tail;
        * tail = now;
        // 输入具体信息
        {
            puts("Input commodity name:");
            scanf("%s", now->commodityName);
            puts("Input commodity unit price:");

            char tempUnitPrice[STR_MAX_LEN];
            scanf("%s", tempUnitPrice);
            while(!(isStandardFloat(tempUnitPrice) || isFullDigit(tempUnitPrice))
            && strlen(tempUnitPrice) <= 8)
            {
                puts("Illegal input Detected!Try again:");
                scanf("%s", tempUnitPrice);
            }
            if(isStandardFloat(tempUnitPrice)==true)
                now->soldPrice = strToDouble(tempUnitPrice);
            else if(isFullDigit(tempUnitPrice)==true)
                now->soldPrice = intStrToDouble(tempUnitPrice);

            puts("Input commodity purchase price:");
            char tempPurchasePrice[STR_MAX_LEN];
            scanf("%s", tempPurchasePrice);
            while(!(isStandardFloat(tempPurchasePrice) || isFullDigit(tempPurchasePrice))
                  && strlen(tempPurchasePrice) <= 8)
            {
                puts("Illegal input Detected!Try again:");
                scanf("%s", tempPurchasePrice);
            }//解决输入不知道加没加小数点的情况
            if(isStandardFloat(tempPurchasePrice)==true)
                now->purchasePrice = strToDouble(tempPurchasePrice);
            else if(isFullDigit(tempPurchasePrice)==true)
                now->purchasePrice = intStrToDouble(tempPurchasePrice);
        }
        return ;
    }
}
void getUnitCount(struct RecordNode ** head, struct CommodityNode *p)
{
    if(* head == NULL || p == NULL)
        return;
    struct RecordNode * searchPtr = * head;
    int tempUnitCount=0;
    while(searchPtr != NULL)
    {
        if(strcmp(searchPtr->commodityName, p->commodityName) == 0)
        {
            if(searchPtr->isSoldOut == true)
                tempUnitCount -= searchPtr->unitCount;
            else if(searchPtr->isSoldOut == false)
                tempUnitCount += searchPtr->unitCount;
        }
        searchPtr = searchPtr->nextRecord;
    }
    p->unitCount = tempUnitCount;//将p的unitCount进行赋值
}




